<title>Showing Progress in Eclipse</title>
<table border="0" cellspacing="5" cellpadding="2" width="100%">
  
    <tr> 
      
    <td align="left" valign="top" bgcolor="#0080c0"> <b><font color="#ffffff" face="Arial,Helvetica"> 
      Eclipse 3.0 - Responsiveness Plan Item</font></b> </td>
    </tr>
</table>
<h1>Showing progress in Eclipse 3.0</h1>
<p>This document outlines the initial thoughts on progress support in Eclipse 
  3.0. It's basically a summary of the discussions we have had around this subject.</p>
<p>By: Jean-Michel Lemieux, 2003-09-24</p>
<p> Participants: Mike Wilson, Nick Edgar, John Arthorne, Tod Creasey</p>
<h2>Motivation</h2>
<p>In Eclipse 2.1 long running operations blocked the user interface via a progress 
  dialog, busy cursor, or a progress indicator shown in another context (e.g. 
  workbench, wizard). There are several APIs used by plugin developers for this 
  purpose. There are actually too many choices for plugin developers to make in 
  deciding how to show progress. This has resulted in the following symptoms:</p>
<ul>
  <li>Too much work is performed in the UI thread. This can cause the application 
    window to stop painting. Most of these problems are caused by progress APIs 
    that don't actually fork to perform the work (e.g. BusyIndicator, BusyIndicatorRunnableContext).</li>
  <li>Progress is not shown consistently in the workbench. Should you use a progress 
    dialog, busy indicator, or use the workbench progress indicator?</li>
  <li>Plugin developers would decide that an operation shouldn't take too long 
    and use a busy indicator. But the actual time an operation requires can very 
    and a busy indicator is not cancelable. To compound this, there are no APIs 
    in Eclipse to show a busy indicator while performing the actual work in another 
    thread.</li>
  <li>Since there are so many progress APIs it's hard to provide a framework for 
    progress that would help the plugin developer and provide a more consistent 
    progress story in Eclipse.</li>
  <li>The new Jobs API in org.eclipse.runtime is providing another way of looking 
    at progress. In 3.0 there will be model and non-model operations. Both require 
    progress and model operations can potentially be blocked by a or many non-model 
    operations. </li>
</ul>
<h2>Current APIs</h2>
<pre>
/************************
 * Modal Progress APIs
 ************************/


/* Shows a busy cursor and runs the runnable in the current thread. */
org.eclipse.swt.custom.BusyIndicator::showWhile(Display display, Runnable runnable);



/* Allows an operation to run either in the current thread or in another thread. If the
   current thread is the UI thread the event queue is read and dispatched. */
org.eclipse.jface.operations.ModalContext::run(run(IRunnableWithProgress operation, boolean fork, IProgressMonitor monitor, Display display);



/* Is implemented by several contexts: workbench window, progress dialog, busy indicator
   wizards. Allows to run an operation in the current thread or in another thread while
   showing progress in the given context. The user can decide if the operation can be
   cancelled. */
org.eclipse.jface.operations.IRunnableContext::run(boolean fork, boolean cancelable, IRunnableWithProgress runnable);


/************************
 * Non-Modal Progress APIs
 ************************/


/* Runs an operation in a separate thread showing progress via a registered progress service. The
   Job can be cancelled via the progress monitor. */
org.eclipse.runtime.jobs.Job::run(IProgressMonitor monitor);
</pre>

 
<h2>Elements of a solution</h2>
<p>Here is a list of progress issues that we would like to address in 3.0. </p>
<ol>
  <li>Support for showing modal and non-modal progress in a cohesive way. Make 
    it easy for plugin developers to say &quot;run this operation&quot; without 
    having to decide about the particular mechanism should be used to display 
    progress. This would allow the platform to implement a standard progress strategy.</li>
  <li>Support for allowing the user to cancel a model operation that is blocked 
    by a non-modal operation. This can happen when a modal operation cannot run 
    until a non-modal operation completes. </li>
  <li>Support for showing non-modal progress in a view/editor. This means that 
    when an non-modal operation affects a view/editor the user should get feedback 
    that the views is doing work.</li>
  <li>Support for showing non-model progress when populating a viewer (e.g. tree 
    viewer, table viewer).</li>
</ol>
<h3>Cohesive modal and non-modal progress</h3>
<p>Instead of the user having to decide where and how to show progress, the platform 
  should provide a single method for displaying modal progress. This single progress 
  API could enforce that work is never performed in the UI thread, fine grain 
  cancellation is supported, and progress is shown consistently.</p>
<p>Summary: We would require a single API for running a modal operation. Can have 
  the same parameters as IRunnableContext and existing implementations of IRunnableContext 
  could delegate to a new progress service. In addition, wizards could continue 
  to be a IRunnableContext but should support showing the fine grain cancellation 
  hint. A single API would allow the platform UI team to experiment with different 
  ways of showing progress and have it apply to all operations. For example, you 
  could imagine that a good solution for a common progress story to include a 
  combined busy cursor with a delayed progress indicator.</p>
<h3>Fine grain cancellation</h3>
<p>It's now possible to any operation that modifies the workspace to block for 
  an unknown amount of time while a non-modal operation has a lock on the workspace 
  or resources required by the modal operation. The user should minimally:</p>
<ol>
  <li>See that the modal operation is blocked by another operation. </li>
  <li>Be able to cancel the modal operation.</li>
  <li>Wait for the non-modal operation to finish and let the modal operation continue 
    afterwards.</li>
  <li>(optionally) be able to cancel the non-modal operation that's blocking the 
    modal one.</li>
</ol>
<p>The notification of a modal operation being blocked by a non-modal must be 
  smart and non-intrusive. It is quite possible that blocking is resolved quickly 
  and the user should not have to know that there was a small delay in starting 
  the operation. For example, it wouldn't be good to pop-up a dialog every time 
  a modal operation is blocked.</p>
<p>To support this an extension to IProgressMonitor will have to be created to 
  allow the resources plugin to notify the progress service that an operation 
  is being blocked.</p>
<h3>Progress for non-modal operations affecting a view/editor</h3>
<p>With more plugins using non-modal operations to update views and editors it 
  is useful for the user to understand when a view/editors content is being changed 
  by a non-modal operation. We should add an API for associated a non-modal operation 
  (e.g. a org.eclipse.runtime.Job) with a IWorkbenchPartSite. This would allow 
  the platform UI team to experiment with methods of showing non-modal progress 
  in a view or editor.</p>
<p>For scheduling a non-modal operation the developer would have to decide if 
  the job affects a view. And if it does than call something similar to:</p>
  
<pre>
view.getSite().schedule(aJob);
editorPart.getSite().schedule(aJob);</pre>
<p>And if a non-modal operation doesn't affect a particular view, it would be 
  scheduled and progress shown via the standard non-modal progress support:</p>
<pre>aJob.schedule();</pre>
<h3>Progress for non-modal populating of a viewer</h3>
<p>When a non-modal operation is populating a viewer (e.g. fetching children for 
  a tree node, or fetching members for a table) it may be useful to show the user 
  a hint that the viewer is not showing the complete results. For a tree viewer 
  it may be useful to show the progress hint for each sub-folder (e.g. the 'pending' 
  placeholder in the CVS repositories view) and for a table viewer simply clearing 
  the view than showing the non-modal progress for a view/editor.</p>
<h3>When is it ok to do work in the UI thread?</h3>
<p>If the work can be run in under 100ms and there are no workspace changes made. 
  If either of these requirements are not met, than work should be performed in 
  another thread. For this reason, I recommend that the new progress API remove 
  the fork option and automatically run the operation in another thread while 
  processing the SWT events queue. This implies that the operations that satisfy 
  the conditions for running in the UI thread can continue to use the org.eclipse.swt.custom.BusyIndicator.showWhile() 
  method for displaying progress.</p>
</BODY>
</html>